package com.smartscreen.grademanage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.smartscreen.grademanage.dto.*;
import com.smartscreen.grademanage.entity.Exam;
import com.smartscreen.grademanage.entity.Score;
import com.smartscreen.grademanage.mapper.ExamMapper;
import com.smartscreen.grademanage.mapper.ScoreMapper;
import com.smartscreen.grademanage.service.ScoreService;
import com.smartscreen.baseinfomanage.client.BaseInfoClient;
import com.smartscreen.common.response.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ScoreServiceImpl implements ScoreService {
    
    @Autowired
    private ScoreMapper scoreMapper;
    
    @Autowired
    private ExamMapper examMapper;

    
    @Autowired
    private BaseInfoClient baseInfoClient;
    
    @Override
    @Transactional
    public ScoreImportResponse importScores(String examId, ScoreImportRequest request) {
        ScoreImportResponse response = new ScoreImportResponse();
        List<String> errors = new ArrayList<>();
        int successCount = 0;
        
        for (ScoreImportRequest.ScoreItem item : request.getScores()) {
            try {
                Score score = new Score();
                score.setExamId(examId);
                score.setStudentId(item.getStudentId());
                score.setSubjectId(item.getSubjectId());
                score.setScore(item.getScore());
                
                scoreMapper.insert(score);
                successCount++;
            } catch (Exception e) {
                errors.add("学生ID: " + item.getStudentId() + ", 科目ID: " + item.getSubjectId() + " - " + e.getMessage());
            }
        }
        
        response.setSuccessCount(successCount);
        response.setFailureCount(request.getScores().size() - successCount);
        response.setErrors(errors);
        
        return response;
    }
    
    @Override
    public List<StudentScoreResponse> getStudentScores(String studentId, String termId, String examId) {
        // 1. 获取成绩数据（不包含关联信息）
        List<Score> scores = scoreMapper.getStudentScores(studentId, termId, examId);
        
        if (scores.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 2. 批量获取考试信息
        Set<String> examIds = scores.stream().map(Score::getExamId).collect(Collectors.toSet());
        Map<String, Exam> examMap = new HashMap<>();
        if (!examIds.isEmpty()) {
            List<Exam> exams = examMapper.selectBatchIds(examIds);
            examMap = exams.stream().collect(Collectors.toMap(Exam::getId, exam -> exam));
        }
        
        // 3. 通过代理对象批量获取科目信息
        Set<String> subjectIds = scores.stream().map(Score::getSubjectId).collect(Collectors.toSet());
        Map<String, Map<String, Object>> subjectMap = new HashMap<>();
        if (!subjectIds.isEmpty()) {
            try {
                subjectMap = baseInfoClient.getSubjectsBatch(new ArrayList<>(subjectIds));
            } catch (Exception e) {
                // 处理远程调用异常
                System.err.println("获取科目信息失败: " + e.getMessage());
            }
        }
        
        final Map<String, Exam> finalExamMap = examMap;
        final Map<String, Map<String, Object>> finalSubjectMap = subjectMap;
        
        // 4. 组装响应数据
        return scores.stream().map(score -> {
            StudentScoreResponse response = new StudentScoreResponse();
            
            // 获取考试名称
            Exam exam = finalExamMap.get(score.getExamId());
            response.setExamName(exam != null ? exam.getExamName() : "未知考试");
            
            // 通过代理对象获取科目名称
            Map<String, Object> subject = finalSubjectMap.get(score.getSubjectId());
            response.setSubjectName(subject != null ? (String) subject.get("subjectName") : "未知科目");
            
            response.setScore(score.getScore());
            response.setClassRank(score.getClassRank());
            response.setGradeRank(score.getGradeRank());
            return response;
        }).collect(Collectors.toList());
    }
    
    @Override
    public ClassScoreResponse getClassScores(String classId, String examId) {
        ClassScoreResponse response = new ClassScoreResponse();
        
        try {
            // 1. 通过代理对象获取班级下的所有学生ID
            ApiResponse<List<String>> studentIdsResponse = baseInfoClient.getStudentIdsByClassId(classId);
            if (studentIdsResponse == null || studentIdsResponse.getData() == null || studentIdsResponse.getData().isEmpty()) {
                response.setScores(new ArrayList<>());
                return response;
            }
            
            List<String> studentIds = studentIdsResponse.getData();
            
            // 2. 根据学生ID列表获取成绩
            List<Score> scores = scoreMapper.getScoresByStudentIds(examId, studentIds);
            
            // 3. 获取考试信息
            Exam exam = examMapper.selectById(examId);
            response.setExamName(exam != null ? exam.getExamName() : "未知考试");
            
            if (scores.isEmpty()) {
                response.setScores(new ArrayList<>());
                return response;
            }
            
            // 4. 通过代理对象批量获取学生信息
            Set<String> scoreStudentIds = scores.stream().map(Score::getStudentId).collect(Collectors.toSet());
            Map<String, Map<String, Object>> studentMap = new HashMap<>();
            if (!scoreStudentIds.isEmpty()) {
                try {
                    studentMap = baseInfoClient.getStudentsBatch(new ArrayList<>(scoreStudentIds));
                } catch (Exception e) {
                    System.err.println("获取学生信息失败: " + e.getMessage());
                }
            }
            
            // 5. 通过代理对象批量获取科目信息
            Set<String> subjectIds = scores.stream().map(Score::getSubjectId).collect(Collectors.toSet());
            Map<String, Map<String, Object>> subjectMap = new HashMap<>();
            if (!subjectIds.isEmpty()) {
                try {
                    subjectMap = baseInfoClient.getSubjectsBatch(new ArrayList<>(subjectIds));
                } catch (Exception e) {
                    System.err.println("获取科目信息失败: " + e.getMessage());
                }
            }
            
            // 6. 按学生分组处理成绩
            Map<String, List<Score>> studentScores = scores.stream()
                    .collect(Collectors.groupingBy(Score::getStudentId));
            
            List<ClassScoreResponse.StudentScore> studentScoreList = new ArrayList<>();
            
            final Map<String, Map<String, Object>> finalStudentMap = studentMap;
            final Map<String, Map<String, Object>> finalSubjectMap = subjectMap;
            
            for (Map.Entry<String, List<Score>> entry : studentScores.entrySet()) {
                ClassScoreResponse.StudentScore studentScore = new ClassScoreResponse.StudentScore();
                studentScore.setStudentId(entry.getKey());
                
                // 通过代理对象获取学生姓名
                Map<String, Object> student = finalStudentMap.get(entry.getKey());
                studentScore.setStudentName(student != null ? (String) student.get("name") : "未知学生");
                
                // 处理各科目成绩
                List<ClassScoreResponse.SubjectScore> subjectScores = entry.getValue().stream()
                        .map(score -> {
                            ClassScoreResponse.SubjectScore subjectScore = new ClassScoreResponse.SubjectScore();
                            
                            // 通过代理对象获取科目名称
                            Map<String, Object> subject = finalSubjectMap.get(score.getSubjectId());
                            subjectScore.setSubjectName(subject != null ? (String) subject.get("subjectName") : "未知科目");
                            subjectScore.setScore(score.getScore());
                            return subjectScore;
                        }).collect(Collectors.toList());
                
                studentScore.setSubjectScores(subjectScores);
                
                // 计算总分
                BigDecimal totalScore = entry.getValue().stream()
                        .map(Score::getScore)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                studentScore.setTotalScore(totalScore);
                
                studentScoreList.add(studentScore);
            }
            
            response.setScores(studentScoreList);
            
        } catch (Exception e) {
            System.err.println("获取班级成绩失败: " + e.getMessage());
            response.setScores(new ArrayList<>());
        }
        
        return response;
    }
    
    @Override
    public ExamAnalysisResponse getExamAnalysis(String examId, String scope, String scopeId) {
        // 根据scope和scopeId查询相应范围的成绩
        QueryWrapper<Score> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("exam_id", examId);
        
        // 根据scope添加额外的查询条件
        if ("class".equals(scope) && scopeId != null) {
            // 如果是班级范围，需要通过学生信息过滤
            // 这里可以根据实际需求添加更复杂的查询逻辑
        }
        
        List<Score> scores = scoreMapper.selectList(queryWrapper);
        
        ExamAnalysisResponse response = new ExamAnalysisResponse();
        
        // 获取科目信息
        Set<String> subjectIds = scores.stream().map(Score::getSubjectId).collect(Collectors.toSet());
        Map<String, Map<String, Object>> subjectMap = new HashMap<>();
        if (!subjectIds.isEmpty()) {
            subjectMap = baseInfoClient.getSubjectsBatch(new ArrayList<>(subjectIds));
        }
        
        // 按科目分组进行分析
        Map<String, List<Score>> subjectScores = scores.stream()
                .collect(Collectors.groupingBy(Score::getSubjectId));
        
        List<ExamAnalysisResponse.SubjectAnalysis> subjectAnalysisList = new ArrayList<>();
        
        final Map<String, Map<String, Object>> finalSubjectMap = subjectMap;
        
        for (Map.Entry<String, List<Score>> entry : subjectScores.entrySet()) {
            ExamAnalysisResponse.SubjectAnalysis analysis = new ExamAnalysisResponse.SubjectAnalysis();
            
            // 获取科目名称
            Map<String, Object> subject = finalSubjectMap.get(entry.getKey());
            analysis.setSubjectName(subject != null ? (String) subject.get("subjectName") : "未知科目");
            
            List<BigDecimal> scoreList = entry.getValue().stream()
                    .map(Score::getScore)
                    .collect(Collectors.toList());
            
            // 计算统计数据
            BigDecimal average = scoreList.stream()
                    .reduce(BigDecimal.ZERO, BigDecimal::add)
                    .divide(BigDecimal.valueOf(scoreList.size()), 2, BigDecimal.ROUND_HALF_UP);
            
            analysis.setAverageScore(average);
            analysis.setHighestScore(scoreList.stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO));
            analysis.setLowestScore(scoreList.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO));
            
            long passCount = scoreList.stream().filter(score -> score.compareTo(BigDecimal.valueOf(60)) >= 0).count();
            String passRate = String.format("%.1f%%", (double) passCount / scoreList.size() * 100);
            analysis.setPassRate(passRate);
            
            // 分数段分布
            Map<String, Integer> distribution = new HashMap<>();
            distribution.put("90-100", (int) scoreList.stream().filter(s -> s.compareTo(BigDecimal.valueOf(90)) >= 0).count());
            distribution.put("80-89", (int) scoreList.stream().filter(s -> s.compareTo(BigDecimal.valueOf(80)) >= 0 && s.compareTo(BigDecimal.valueOf(90)) < 0).count());
            distribution.put("70-79", (int) scoreList.stream().filter(s -> s.compareTo(BigDecimal.valueOf(70)) >= 0 && s.compareTo(BigDecimal.valueOf(80)) < 0).count());
            distribution.put("60-69", (int) scoreList.stream().filter(s -> s.compareTo(BigDecimal.valueOf(60)) >= 0 && s.compareTo(BigDecimal.valueOf(70)) < 0).count());
            distribution.put("<60", (int) scoreList.stream().filter(s -> s.compareTo(BigDecimal.valueOf(60)) < 0).count());
            
            analysis.setScoreDistribution(distribution);
            subjectAnalysisList.add(analysis);
        }
        
        response.setSubjectAnalysis(subjectAnalysisList);
        response.setAiInsights("本次考试，高分段学生占比较高，但仍有少数学生在及格线边缘，建议关注基础题型的掌握情况。");
        
        return response;
    }
}